package com.ruoyi.teaching.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.li.work.mapper.SysUserMapper;
import com.ruoyi.li.work.mapper.SysUserRoleMapper;
import com.ruoyi.teaching.domain.PlatformEEventResult;
import com.ruoyi.teaching.domain.UniversalCreateUpdate;
import com.ruoyi.teaching.mapper.PlatformEEventResultMapper;
import com.ruoyi.teaching.service.PlatformEEventResultService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.teaching.utils.UniversalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 王旭
 * @since 2025-03-04
 */
@Service
public class PlatformEEventResultServiceImpl extends ServiceImpl<PlatformEEventResultMapper, PlatformEEventResult> implements PlatformEEventResultService {
    @Autowired
    private PlatformEEventResultMapper platformEEventResultMapper;
    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Override
    public AjaxResult addEventResult(PlatformEEventResult eventResult) {
        UniversalCreateUpdate createUpdate = UniversalUtil.getCreateUpdate(userMapper);
        eventResult.setCreateBy(createUpdate.getName());
        eventResult.setCreateTime(DateUtils.getNowDate());
        eventResult.setCreateId(createUpdate.getId());
        int insert = platformEEventResultMapper.insert(eventResult);
        if (insert > 0) {
            return new AjaxResult(HttpStatus.SUCCESS, "添加成功");
        } else {
            return new AjaxResult(HttpStatus.ERROR, "添加失败");
        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public AjaxResult deleteEventResultByIds(Long[] ids) {
        int i1 = platformEEventResultMapper.deleteBatchIds(Arrays.asList(ids));
        if (i1 == ids.length) {
            return new AjaxResult(HttpStatus.SUCCESS, "删除成功");
        }
        throw new RuntimeException("删除失败");
    }

    @Override
    public AjaxResult selectListEventResult(Integer pageNum, Integer pageSize, String eventName, Integer eventLevel, Integer professionalCategoryId) {
        int roleId = 0;
        Long userId = SecurityUtils.getUserId();
        if (userId != null) {
            roleId = Math.toIntExact(sysUserRoleMapper.selectRoleIdbyUserId(userId)[0]);
        }
        if (roleId != 2 && roleId != 6 && roleId != 1) {
            return new AjaxResult(HttpStatus.ERROR, "当前角色暂无权限");
        }
        Page<PlatformEEventResult> platformEEventResultPage = new Page<>(pageNum, pageSize);
        QueryWrapper<PlatformEEventResult> platformEEventResultQueryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(eventName)) {
            platformEEventResultQueryWrapper.like("event_name", eventName);
        }
        if (eventLevel != null) {
            platformEEventResultQueryWrapper.eq("event_level", eventLevel);
        }
        if (professionalCategoryId != null) {
            platformEEventResultQueryWrapper.eq("professional_category_id", professionalCategoryId);
        }
        if (roleId == 2) {
            platformEEventResultQueryWrapper.eq("create_id", userId);
        }
        platformEEventResultQueryWrapper.orderByDesc("create_time");
        platformEEventResultPage = platformEEventResultMapper.selectPage(platformEEventResultPage, platformEEventResultQueryWrapper);
        return new AjaxResult(HttpStatus.SUCCESS, "查询成功", platformEEventResultPage);
    }

    // 锁缓存，按 ID 维度管理，每个 ID 一把锁
    private final ConcurrentHashMap<Long, ReadWriteLock> lockMap = new ConcurrentHashMap<>();

    @Override
    public AjaxResult addViewCount(Long id) {
        // 获取对应 ID 的锁，保证线程安全
        ReadWriteLock rwLock = lockMap.computeIfAbsent(id, k -> new ReentrantReadWriteLock());
        Lock writeLock = rwLock.writeLock();

        writeLock.lock();
        try {
            PlatformEEventResult platformEEventResult = platformEEventResultMapper.selectById(id);
            if (platformEEventResult != null) {
                // 增加查看次数
                platformEEventResult.setLookNum(platformEEventResult.getLookNum() + 1);
                int update = platformEEventResultMapper.updateById(platformEEventResult);

                if (update > 0) {
                    return new AjaxResult(HttpStatus.SUCCESS, "添加成功");
                } else {
                    return new AjaxResult(HttpStatus.ERROR, "添加失败");
                }
            }
            return new AjaxResult(HttpStatus.SUCCESS, "查询失败");
        } finally {
            writeLock.unlock();

            // 释放锁时判断是否可以清理锁
            lockMap.compute(id, (key, value) -> value != null &&
                    value.writeLock().tryLock() && value.readLock().tryLock() ? null : value);
        }
    }

    @Override
    public AjaxResult getResultById(Long id) {
        PlatformEEventResult platformEEventResult = platformEEventResultMapper.selectById(id);
        return new AjaxResult(HttpStatus.SUCCESS, "查询成功", platformEEventResult);
    }
}
